Contemporary operating systems include a number of components, such as in the form of dynamic link libraries, or DLLS, which are loaded to provide functions to applications, other operating system components, and other code such as services and drivers. As a result of security issues and other bugs being discovered, these components need to be updated from time to time.
Developers of operating systems thus occasionally release security and other fixes to a core system component, which on any given computer is essentially always available for use by services that may enter and leave the core component code routine asynchronously relative to any update. Since the component code is in use, this component cannot be replaced without requiring a reboot, or some locking mechanism that prevents the code from being used while it is updated, but significantly lowers performance. For example, even if an installer is able to replace the component using a replacement mechanism having very little delay, the service which is using the component will not get the fix until reboot. As a result, to install the security fix, which may be critical to secure the computer, the system requires rebooting, which means a loss of service for a customer.
As another example, a network administrator may wish to patch components throughout the network that have been threatened by a virus. However, the patched code will not begin running on a system until each patched system is rebooted, causing a substantial amount of system downtime in the network, leading to customer inconvenience and loss of revenue.
Thus, updating software components on customer systems typically requires a reboot, because updates replace components at the file level (e.g. DLLs or EXEs), and these components may be in use by long running applications or services. This is because replacing components while they are in use cannot be performed safely, as a result of addresses stored within running code becoming invalid when the replacement is loaded. Similarly, a reboot is performed to patch other components that are only loaded at boot, such as kernel components, the hardware abstraction layer (HAL), and boot drivers.
Solutions to this booting problem exist, but require a component to be totally unloaded, patched, and then reloaded. One way to do this is by killing any processes that use the component, apply the patch and restart the processes. These solutions are also undesirable to customers, as like rebooting, they lead to loss of service and revenue. Many customers choose to not deploy patches for this reason, instead risking exposure to the security threats and/or bugs that the patch has been developed to fix.
For some standalone services, shutting down the applications and services that use a component that is targeted to be patched causes the component to be unloaded, whereby the patch may be safely applied. This technique does not work with many types of components, however, (e.g., services running in a service host, or SvcHost process), because these types of components are not necessarily unloaded when an individual application or service is shutdown. Moreover, having key services become even temporarily unavailable when they are expected to be present may cascade failures throughout a system or network.
What is needed is a safe and comprehensive solution to updating software components on computer systems that significantly reduces the number of reboots or other service interruptions on those customer machines, and in such a way as to not disrupt current running services or cause data loss. When reboots are not needed, customers are more likely to apply security and other fixes quickly, e.g., as they are released.